package com.ice.framework.web.config;

import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.http.converter.xml.SourceHttpMessageConverter;

import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * 自定义全局转换器。
 *
 * <br/> 由于springMVC与RestTemplate各自定义了自己的转换器，需要同时处理
 * 	且需要对原转换器做以下替换：
 * 	（1）替换String转换器，将字符集设置为UTF-8
 *  （2）替换JSON转换器，使用FastJson转换器
 * 	（3）由于没有使用到JSON转XML的转换器，去掉了json2Xml转换器（该转换器在JSON之前被匹配）。
 * @author 
 * @Date 2021/12/31 17:01
 */
@Configuration
public class HttpMessageConvertersConfig {

    private static final String DATE_FORMAT = "yyyy-MM-dd";

    private static final String ENCODING = "utf-8";

    //可配置日期转化格式
    @Value("${spring.dateformat:yyyy-MM-dd HH:mm:ss}")
    private String dateformat;

    @Bean
    public HttpMessageConverters HttpMessageConverters() {

        List<HttpMessageConverter<?>> list = new ArrayList<>();

        list.add(new ByteArrayHttpMessageConverter());

        list.add(stringHttpMessageConverter());

        list.add(new ResourceHttpMessageConverter(false));

        list.add(new SourceHttpMessageConverter<>());

        list.add(new AllEncompassingFormHttpMessageConverter());

        list.add(fastJsonHttpMessageConverter());

        HttpMessageConverters converters = new HttpMessageConverters(false,list);

        return converters;
    }


    /**
     * StringHttpMessageConverter 设置字符（系统默认为ISO）
     *
     * @return
     *
     * @author wangwei
     *
     * @since 2018年7月5日
     */
    private StringHttpMessageConverter stringHttpMessageConverter() {
        StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
        //设置编码
        stringConverter.setDefaultCharset(Charset.forName(ENCODING));
        stringConverter.setWriteAcceptCharset(false);

        return stringConverter;
    }

    /**
     * 使用FastJSON转换器（默认使用 MappingJackson2HttpMessageConverter）
     *
     * @return
     *
     * @author wangwei
     *
     * @since 2018年7月5日
     */
    private FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();

        fastConverter.setFastJsonConfig(initFastJsonConfig(dateformat));

        List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();

        supportedMediaTypes.add(MediaType.APPLICATION_JSON);

        fastConverter.setSupportedMediaTypes(supportedMediaTypes);

        return fastConverter;
    }

    public static FastJsonConfig initFastJsonConfig(String dateformat) {
        if(dateformat == null) {
            dateformat = DATE_FORMAT;
        }
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
        //fastJsonConfig.setSerializeFilters(new BigdecimalValueFilter());

        fastJsonConfig.setSerializerFeatures(
                // 使用日期格式
                SerializerFeature.WriteDateUseDateFormat,
                SerializerFeature.UseISO8601DateFormat,
                SerializerFeature.DisableCircularReferenceDetect,
                // 避免循环引用
                SerializerFeature.DisableCircularReferenceDetect
        );
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
        serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
        serializeConfig.put(Long.class, ToStringSerializer.instance);
        serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
        //针对
        fastJsonConfig.setSerializeConfig(serializeConfig);
        //全局指定了日期格式
        fastJsonConfig.setDateFormat(dateformat);
        return fastJsonConfig;
    }

}
